package com.atguigu.yygh.common.helper;

import io.jsonwebtoken.*;
import org.springframework.util.StringUtils;

import java.util.Date;

/**
 * JwtHelper 类用于处理 JWT（JSON Web Token）的生成、解析和验证。
 */
public class JwtHelper {

    // 定义 token 的过期时间，这里设置为 100 年
    private static long tokenExpiration = 100*365*24*60*60*1000;
    // 定义用于签名 token 的密钥
    private static String tokenSignKey = "123456";

    /**
     * 创建一个新的 JWT token。
     *
     * @param userId 用户 ID。
     * @param userName 用户名。
     * @return 生成的 JWT token。
     */
    public static String createToken(Long userId, String userName) {
        // 使用 Jwts.builder() 创建一个新的 JWT token
        String token = Jwts.builder()
                // 设置 token 的主题为 "P2P-USER"
                .setSubject("P2P-USER")
                // 设置 token 的过期时间为当前时间加上 tokenExpiration
                .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))
                // 添加一个声明，键为 "userId"，值为 userId
                .claim("userId", userId)
                // 添加一个声明，键为 "userName"，值为 userName
                .claim("userName", userName)
                // 使用 HS512 算法和 tokenSignKey 对 token 进行签名
                .signWith(SignatureAlgorithm.HS512, tokenSignKey)
                // 使用 GZIP 压缩算法对 token 进行压缩
                .compressWith(CompressionCodecs.GZIP)
                // 生成并返回 token
                .compact();
        return token;
    }

    /**
     * 从 JWT token 中获取用户 ID。
     *
     * @param token JWT token。
     * @return 用户 ID，如果 token 无效或过期则返回 null。
     */
    public static Long getUserId(String token) {
        // 如果 token 为空，则返回 null
        if(StringUtils.isEmpty(token)) return null;

        try {
            // 使用 Jwts.parser() 解析 token，并设置签名密钥为 tokenSignKey
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
            // 从解析后的 token 中获取声明
            Claims claims = claimsJws.getBody();
            // 从声明中获取 "userId" 并转换为 Integer 类型
            Integer userId = (Integer)claims.get("userId");
            // 将 Integer 类型的 userId 转换为 Long 类型并返回
            return userId.longValue();
        } catch (Exception e) {
            // 如果解析过程中出现异常，返回 null
            return null;
        }
    }

    /**
     * 从 JWT token 中获取用户名。
     *
     * @param token JWT token。
     * @return 用户名，如果 token 无效或过期则返回空字符串。
     */
    public static String getUserName(String token) {
        // 如果 token 为空，则返回空字符串
        if(StringUtils.isEmpty(token)) return "";

        try {
            // 使用 Jwts.parser() 解析 token，并设置签名密钥为 tokenSignKey
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
            // 从解析后的 token 中获取声明
            Claims claims = claimsJws.getBody();
            // 从声明中获取 "userName" 并返回
            return (String)claims.get("userName");
        } catch (Exception e) {
            // 如果解析过程中出现异常，返回空字符串
            return "";
        }
    }

    /**
     * 移除（使失效）一个 JWT token。
     *
     * @param token JWT token。
     * 实际上，JWT token 一旦生成就无法被移除，客户端只需丢弃该 token 即可。
     */
    public static void removeToken(String token) {
        // jwttoken 无需删除，客户端扔掉即可。
    }

    /**
     * 主函数，用于测试 JwtHelper 类的功能。
     *
     * @param args 命令行参数。
     */
    public static void main(String[] args) {
        // 生成一个测试用的 JWT token
        String token = JwtHelper.createToken(1L, "admin");
        // 打印生成的 token
        System.out.println(token);
        // 打印从 token 中获取的用户 ID
        System.out.println(JwtHelper.getUserId(token));
        // 打印从 token 中获取的用户名
        System.out.println(JwtHelper.getUserName(token));
    }
}
